/**
 * Empreendimento.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package negocio.pessoas;

import persistencia.pessoas.PEmpreendimento;
import transacoes.TRNManterEmpreendimento;
import java.util.*;
import persistencia.notas.PNota;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class Empreendimento {

    // <editor-fold defaultstate="collapsed" desc="FIELDS">
    private String cod_objeto;
    private int status;
    private String pessoa;
    private Date dataInicio = null;
    private Date dataTermPrevisto = null;
    private Date dataTermEfetivo = null;
    private Date dtVenda = null;
    private double valorVenda;
    private Boolean update;
    private Boolean isNew = true;
    private String errorMessage;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="ACESSORES">
    // Atributo cod_objeto
    public String getCod_objeto() {
        return cod_objeto; }
    public void setCod_objeto(String cod_objeto) {
        this.cod_objeto = cod_objeto; }
    // Atributo status
    public int getStatus() {
        return status; }
    public void setStatus(int status) {
        this.status = status; }
    // Atributo pessoa
    public String getPessoa() {
        return pessoa; }
    public void setPessoa(String pessoa) {
        this.pessoa = pessoa; }
    // Atributo dataInicio
    public Date getDataInicio() {
        return dataInicio; }
    public void setDataInicio(Date dataInicio) {
        this.dataInicio = dataInicio; }
    // Atributo dataTermPrevisto
    public Date getDataTermPrevisto() {
        return dataTermPrevisto; }
    public void setDataTermPrevisto(Date dataTermPrevisto) {
        this.dataTermPrevisto = dataTermPrevisto; }
    // Atributo dataTermEfetivo
    public Date getDataTermEfetivo() {
        return dataTermEfetivo; }
    public void setDataTermEfetivo(Date dataTermEfetivo) {
        this.dataTermEfetivo = dataTermEfetivo; }
    // Atributo dtVenda
    public Date getDtVenda() {
        return dtVenda; }
    public void setDtVenda(Date dtVenda) {
        this.dtVenda = dtVenda; }
    // Atributo valorVenda
    public double getValorVenda() {
        return valorVenda; }
    public void setValorVenda(double valorVenda) {
        this.valorVenda = valorVenda; }
    // Atributo update
    public Boolean getWasUpdated() {
        return update; }
    public void setWasUpdated(Boolean update) {
        this.update = update; }
    // Atributo isNew
    public void setIsNew(Boolean isNew) {
        this.isNew = isNew; }
    // Atributo errorMessage
    public String getErrorMessage() {
        return errorMessage; }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    public Empreendimento(){
        this.status = StatusEmpreendimento.ABERTO;
        this.update = false;
        this.isNew = true;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="METHODS">
    /**
     * Verifica se um objeto e novo
     * @return retorna verdadeiro se o objeto for novo
     */
    public Boolean isNew(){
        return this.isNew;
    }

    /**
     * Responsavel por inserir os objetos:
     * Pessoa, Endereco, Empreendimento e Telefone
     * @param p objeto pessoa a ser inserido
     * @param e objeto endereco a ser inserido
     * @param lstTelefones lista de telefones para insercao
     * @return TRUE se todas as instrucoes tiverem exito FALSE caso contrario
     */
    public Boolean insert(Pessoa p, Endereco e,
                                            ArrayList<Telefone> lstTelefones){
        Boolean insert = true;

        // Valida o investidor recebido e seu respectivo endereco
        if(p.validateFields() && e.validateFields() && validateFields()){

            // Valida todos os telefones recebidos
            if(lstTelefones != null && lstTelefones.size() > 0){
                for(int j = 0; j < lstTelefones.size() && insert; j++){
                    insert = lstTelefones.get(j).validateFields();
                }
            }
            else insert = false;
        }
        else insert = false; 

        try{
            // Verifica se pode inserir
            if(insert) {
                insert = TRNManterEmpreendimento.insert(p, e, this,
                                                                 lstTelefones);

                errorMessage = insert ? "" :
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG;
            }
            else{
                this.errorMessage = ErrorMessage.MSG_GERAL_OBRIG;
            }
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            insert = false;
        }

        return insert;
    }

    /**
     * Responsavel por atualizar os objetos: Pessoa, Endereco e Empreendimento
     * @param p objeto pessoa a ser atualizado
     * @param e objeto endereco a ser atualizado
     * @return TRUE se todas as instrucoes tiverem exito FALSE caso contrario
     */
    public Boolean update(Pessoa p, Endereco e){
        Boolean sit = false;

        try{
            // Valida o investidor recebido e seu respectivo endereco
            if(p.validateFields() && e.validateFields() && validateFields()){
                sit = TRNManterEmpreendimento.update(p, e, this);

                errorMessage = sit ? "" :
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG;
            }
            else{
                errorMessage = ErrorMessage.MSG_GERAL_OBRIG;
            }
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            sit = false;
        }

        return sit;
    }

    /**
     * Responsavel por deletar os objetos:
     * Pessoa, Endereco, Telefones e Empreendimento
     * @param p objeto pessoa a ser deletado
     * @param e objeto endereco a ser deletado
     * @param lstTelefones lista de telefones para delecao
     * @return TRUE se todas as instrucoes tiverem exito FALSE caso contrario
     */
    public Boolean delete(Pessoa p, Endereco e,
                                              ArrayList<Telefone> lstTelefones){
        Boolean delete = true;

        try{
            // Verifica se existe nota vinculada ao empreendimento
            PNota pNota = new PNota();
            if(!pNota.existsEmp(this.cod_objeto)){
                InvestidorEmpreendimento inv = new InvestidorEmpreendimento();

                // Verifica se existe algum investidor relacionado ao empreendimento
                if(!inv.existsInv(cod_objeto)){
                    delete =
                       TRNManterEmpreendimento.delete(p, e, this, lstTelefones);
                    errorMessage = delete ? "" :
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG;
                }
                else{
                    delete = false;
                    errorMessage = ErrorMessage.MSG_EMP_INVRELACIONADO;
                }
            }
            else{
                delete = false;
                errorMessage = ErrorMessage.MSG_EMP_EXCLUSAO;
            }
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            delete = false;
        }

        return delete;
    }

    /**
     * Recupera um empreendimento pelo seu cod_objeto
     * @param cod_objeto codigo do investidor a ser recuperado
     * @return o empreemdimento recuperado
     */
    public Empreendimento refresh(String cod_objeto){
        Empreendimento emp = null;

        try{

            // Verifica se foi informado algum codigo
            if(!cod_objeto.isEmpty()){
                // Recupera o empreendimento em questao
                PEmpreendimento pEmpreendimento = new PEmpreendimento();
                emp = new Empreendimento();

                emp = pEmpreendimento.refresh(cod_objeto);
                this.errorMessage = pEmpreendimento.isError() ?
                                        ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                        ErrorMessage.MSG_GERAL_LOG : "";
            }
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            emp = null;
        }
        return emp;
    }

    /**
     * Recupera um empreendimento pelo seu cod_objeto
     * @param idPessoa identificador da pessoa para recuperacao do empreendimento
     * @return o empreendimento recuperado
     */
    public Empreendimento recEmpreendimentoPessoa(String idPessoa){
        Empreendimento emp = null;

        try{

            // Verifica se foi informado algum codigo
            if(!idPessoa.isEmpty()){
                // Recupera o empreendimento em questao
                PEmpreendimento pEmpreendimento = new PEmpreendimento();
                emp = new Empreendimento();

                emp = pEmpreendimento.recEmpreendimentoPessoa(idPessoa);
                this.errorMessage = pEmpreendimento.isError() ?
                                        ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                        ErrorMessage.MSG_GERAL_LOG : "";
            }
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            emp = null;
        }
        return emp;
    }

    /**
     * Recupera uma lista empreendimentos que satifasca uma situacao
     * @param situacao situacao a ser procurada
     * @return lista de empreendimentos
     */
    public ArrayList<Empreendimento> recLstEmpSituacao(int situacao){
        // Lista de pessoas de retorno
        ArrayList<Empreendimento> lstEmp = new ArrayList<Empreendimento>();

        try{
            // Recupera a lista de empreendimentos
            PEmpreendimento pEmpreendimento = new PEmpreendimento();

            lstEmp = pEmpreendimento.recLstEmprendimentos(situacao);
            this.errorMessage = pEmpreendimento.isError() ?
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG : "";
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            lstEmp = null;
        }

        return lstEmp;
    }

    /**
     * Retorna a soma dos gastos para um dado empreendimento
     * @param idEmp identificador do empreendimento
     * @return soma dos gastos
     */
    public Double sumGastos(String idEmp){
        Double sum = 0.0;

        try{
            if(idEmp.length() > 0){
                PEmpreendimento pEmpreendimento = new PEmpreendimento();
                sum = pEmpreendimento.sumGastos(idEmp);
                this.errorMessage = pEmpreendimento.isError() ?
                                        ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                        ErrorMessage.MSG_GERAL_LOG : "";
            }
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            sum = 0.0;
        }

        return sum;
    }

    // Realiza a validacao dos campos para insercao
    private Boolean validateFields(){
        Boolean ret = true;

        // Verifica se o campo esta marcado como atualizado
        if(this.isNew()) this.cod_objeto = GenerateID.gerarID();

        return ret;
    }
    //</editor-fold>
}